<template>
  <div>
    <div class="table-box">
      <el-table
        ref="tableRef"
        :data="listData"
        :height="tableMaxHeight"
        v-loading="loading"
        element-loading-text="数据加载中..."
        stripe
        :header-cell-class-name="setHeaderClass"
        @sort-change="handleSortChange"
        v-bind="$attrs"
      >
        <template #empty>
          <el-empty />
        </template>

        <template v-for="(item, idx) in columns" :key="item.prop || (item.type && item.type + idx)">
          <!-- 选择多行数据时使用 selection -->
          <el-table-column
            v-if="item.type === 'selection'"
            :fixed="item.fixed || 'left'"
            :align="item.align || 'center'"
            :width="item.width || 48"
            type="selection"
            v-bind="item"
          />

          <!-- 序号 -->
          <el-table-column
            v-if="item.type === 'index'"
            :fixed="item.fixed"
            :align="item.align || 'center'"
            :width="item.width || 50"
            :label="item.label || '序号'"
            type="index"
            :index="item.index || indexMethod"
            :show-overflow-tooltip="item.showOverflowTooltip || false"
            v-bind="item"
          >
            <template #header>
              <Ellipsis :content="item.label" />
            </template>
          </el-table-column>

          <!-- 日期内容 -->
          <el-table-column
            v-if="item.type === 'date'"
            :align="item.align || 'center'"
            :fixed="item.fixed"
            :width="item.width || 160"
            :label="item.label"
            :show-overflow-tooltip="item.showOverflowTooltip || false"
            v-bind="item"
          >
            <template #header>
              <Ellipsis :content="item.label" />
            </template>
            <template #default="{ row }">
              {{ dayjsFormat(row[item.prop as string], item.format) }}
            </template>
          </el-table-column>

          <!-- 常规文本内容 -->
          <!-- <el-table-column
            v-if="!item.type && !item.slotName"
            :align="item.align || 'center'"
            :width="item.width || ''"
            :fixed="item.fixed"
            :label="item.label"
            :prop="item.prop"
            :formatter="item.formatter || undefined"
            :show-overflow-tooltip="item.showOverflowTooltip || false"
            v-bind="item"
          >
            <template #header>
              <Ellipsis :content="item.label" />
            </template>
          </el-table-column> -->

          <!-- 测试 常规文本内容->多级表头 -->
          <el-table-column
            v-if="!item.type && !item.slotName"
            :align="item.align || 'center'"
            :width="item.width || ''"
            :fixed="item.fixed"
            :label="item.label"
            :prop="item.prop"
            :formatter="item.formatter || undefined"
            :show-overflow-tooltip="item.showOverflowTooltip || false"
            v-bind="item"
          >
            <template #header> <Ellipsis :content="item.label" /> </template>
            <template v-if="!item.type && !item.slotName && item.children">
              <el-table-column
                v-for="(child, cIdx) in item.children"
                :key="child.prop || (child.type && child.type + cIdx)"
                :align="child.align || 'center'"
                :width="child.width || ''"
                :fixed="child.fixed"
                :label="child.label"
                :prop="child.prop"
                :formatter="child.formatter || undefined"
                :show-overflow-tooltip="child.showOverflowTooltip || false"
                v-bind="child"
              >
                <template #header> <Ellipsis :content="child.label" /></template>
              </el-table-column>
            </template>
          </el-table-column>

          <!-- 自定义插槽 -->
          <el-table-column
            v-if="!!item.slotName"
            :align="item.align || 'center'"
            :width="item.width || ''"
            :fixed="item.fixed"
            :label="item.label"
            :prop="item.prop"
            :show-overflow-tooltip="item.showOverflowTooltip || false"
            v-bind="item"
          >
            <template #header>
              <Ellipsis :content="item.label" />
            </template>
            <template #default="scope">
              <slot :name="item.slotName" :scope="scope" />
            </template>
          </el-table-column>
        </template>
      </el-table>
    </div>

    <div class="footer-pagination">
      <el-pagination
        v-if="showPagination"
        ref="pageRef"
        v-model:current-page="page.pageNo"
        v-model:page-size="page.pageSize"
        :total="pagination.total"
        :page-sizes="pagination.pageSizes || [10, 20, 30, 50, 100]"
        @current-change="handleCurrentChange"
        @size-change="handleSizeChange"
        background
        layout="total, sizes, prev, pager, next, jumper"
        class="float-right mb-15px mt-15px"
      />
    </div>
  </div>
</template>

<script lang="ts" setup>
// import { getCurrentInstance } from 'vue'
import { ElTable, ElPagination } from 'element-plus'
import { dayjsFormat } from '@/utils/dateUtil'

interface Column {
  type?: 'selection' | 'index' | 'date' | string //  默认的 多选框 和 序号， 自定义的 时间显示 type=='date'的时候  可以多传一个format字段
  prop?: string
  label?: string
  slotName?: string
  align?: string
  width?: number | string
  fixed?: boolean | string
  formatter?: (row: any, column: any, cellValue: any) => any
  showOverflowTooltip?: boolean
  index?: (index: number) => number
  format?: string
  children?: Column[]
}

const props = defineProps({
  // 列表数据源
  listData: {
    type: Array,
    default: () => []
  },
  /**
   * 表头数据源
   * @param {
   *  type:'selection' | 'index' | 'date'  //  默认的 多选框 和 序号， 自定义的 时间显示 type=='date'的时候  可以多传一个format字段
   *  prop: String,
   *  label: String,
   *  slotName: String
   *  支持 Table-column Attributes
   * }
   */
  columns: {
    type: Array as () => Column[],
    default: () => []
  },
  /**
   * 分页数据
   * @param {
   *  pageNum:Number //  当前页码
   *  pageSize: Number, // 每页显示条数
   *  total: Number, // 总条数
   *  pageSizes:[10, 20, 30, 50, 100]
   * }
   */
  pagination: {
    type: Object as () => {
      pageNo: number
      pageSize: number
      total: number
      pageSizes?: number[]
    },
    default: () => ({
      pageNo: 1,
      pageSize: 10,
      total: 0,
      pageSizes: [10, 20, 30, 50, 100]
    })
  },
  loading: {
    type: Boolean,
    default: false
  },
  // 是否显示分页
  showPagination: {
    type: Boolean,
    default: true
  },
  // 是否自动计算表格高度
  heightAuto: {
    type: Boolean,
    default: true
  },
  // 其他内容所占据的高度  by：自动计算高度可能有误差
  otherHeight: {
    type: Number,
    default: 0
  }
})

const emit = defineEmits(['update:pagination', 'getList'])
const attrs = useAttrs()
const tableMaxHeight = ref<number | undefined>(240)
const page = ref({ ...props.pagination })
const tableRef = ref<InstanceType<typeof ElTable> | null>(null)
const pageRef = ref<InstanceType<typeof ElPagination> | null>(null)

const indexMethod = (index: number) => {
  return (props.pagination.pageNo - 1) * props.pagination.pageSize + index + 1
}

const handleCurrentChange = () => {
  emit('update:pagination', page.value)
  emit('getList')
}

const handleSizeChange = () => {
  page.value.pageNo = 1
  emit('update:pagination', page.value)
  emit('getList')
}

// 保存的排序字段
const sortField = ref(new Map<string, any>())
const setHeaderClass = ({ column }: { column: any }): string => {
  if (sortField.value.has(column.property)) {
    column.order = sortField.value.get(column.property)
  }
  return ''
}

// 处理排序字段的格式
const updateOrderBy = () => {
  let sortByList: string[] = []
  let sortByObj: { [key: string]: string } = {}
  for (const [key, value] of sortField.value) {
    if (value) {
      sortByList.push(key + '_' + value)
      sortByObj[key] = value
    }
  }
  console.log('sortField：', sortField.value)
  console.log('sortByList：', sortByList)
  console.log('sortByObj：', sortByObj)
  // return sortByObj
}

// 排序
const handleSortChange = ({ prop, order }: { prop: string; order: any }) => {
  const hasprop = sortField.value.has(prop)
  if (hasprop == true && order == null) {
    sortField.value.delete(prop) //取消排序字段
  } else {
    sortField.value.set(prop, order)
  }

  const sortByObj = updateOrderBy()
  emit('getList', sortByObj)
}

const getTableHeight = () => {
  if (!props.heightAuto) return false
  const $el = tableRef.value?.$el
  const pageScrollTop = document.documentElement.scrollTop || document.body.scrollTop
  const tableOffsetTop = pageScrollTop + ($el?.getBoundingClientRect().top || $el?.offsetTop)
  const windowHeight = window.innerHeight
  let paddingTop = parseFloat(
    window.getComputedStyle($el)?.getPropertyValue('padding-top')?.replace('px', '')
  )
  paddingTop = isNaN(paddingTop) ? 0 : paddingTop
  const paginationHeight = pageRef.value?.$el?.offsetHeight || -10
  const height =
    windowHeight - (tableOffsetTop + paddingTop + paginationHeight + 40 + props.otherHeight)
  tableMaxHeight.value = height ? Math.ceil(Math.max(240, height)) : undefined
}

watch(
  () => props.pagination,
  () => {
    page.value = { ...props.pagination }
  },
  { deep: true }
)

// 更新列表数据的时候，重新计算自动高度
watch(
  () => props.listData,
  () => {
    nextTick(() => {
      getTableHeight()
    })
  },
  { deep: true }
)
// const { proxy } = getCurrentInstance()
// console.log(123333, proxy.$parent.showSearch)
// 监听 父组件 中 Toolbar 的showSearch变化

// // filter组件内的 更多/收起 按钮状态
// searchAreaShow() {
//   return this.$parent?.$refs?.queryForm?.searchAreaShow;
// },

// // 监听 父组件 中 DFilters 的searchAreaShow变化
// searchAreaShow() {
//   this.$nextTick(() => {
//     this.getTableHeight();
//   });
// },

watch(
  () => props.pagination,
  () => {
    nextTick(() => {
      tableRef.value?.doLayout()
    })
  },
  { deep: true }
)
watch(
  () => attrs.showSearch,
  () => {
    nextTick(() => {
      getTableHeight()
    })
  }
)

onMounted(() => {
  nextTick(() => {
    getTableHeight()
  })
})
</script>

<style lang="scss" scoped>
:deep(.table-box .el-table__empty-block) {
  width: 100% !important;
}

:deep(.table-box .el-table--default .cell) {
  display: flex;
  justify-content: center;
  align-items: center;
}

:deep(.el-table .caret-wrapper) {
  width: 14px;

  .sort-caret {
    left: 3px;
  }
  .ascending {
    top: -4px;
  }
  .descending {
    bottom: -5px;
  }
}

@media (max-width: 768px) {
  :deep(.footer-pagination .el-pagination > .el-pagination__jump) {
    display: none !important;
  }
  :deep(.footer-pagination .el-pagination > .el-pagination__sizes) {
    display: none !important;
  }
}

.small-padding {
  .cell {
    padding-left: 5px;
    padding-right: 5px;
  }
}
</style>
